package com.googlecode.connectlet.crypto.cipher.mode;

import com.googlecode.connectlet.crypto.cipher.Encipheror;

public class EcbNoPaddingEncipheror extends EcbCipher {
	protected Encipheror cipher;

	public EcbNoPaddingEncipheror(Encipheror cipher) {
		this.cipher = cipher;
		blockSize = cipher.getBlockSize();
		block = new byte[blockSize];
	}

	protected void encryptNext(byte[] output, int outputOffset) {
		cipher.encrypt(block, 0, output, outputOffset);
	}

	@Override
	public int update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
		int offset = inputOffset;
		int length = inputLen;
		if (blockOffset + length < blockSize) {
			System.arraycopy(input, offset, block, blockOffset, length);
			blockOffset += length;
			return 0;
		}
		int bytesRemain = blockSize - blockOffset;
		System.arraycopy(input, offset, block, blockOffset, bytesRemain);
		offset += bytesRemain;
		length -= bytesRemain;
		encryptNext(output, outputOffset);
		int bytesUpdated = blockSize;
		while (length >= blockSize) {
			System.arraycopy(input, offset, block, 0, blockSize);
			offset += blockSize;
			length -= blockSize;
			encryptNext(output, outputOffset + bytesUpdated);
			bytesUpdated += blockSize;
		}
		System.arraycopy(input, offset, block, 0, length);
		blockOffset = length;
		return bytesUpdated;
	}

	@Override
	public int doFinal(byte[] output, int outputOffset) {
		return 0;
	}
/*
	private static final int CIPHER_BUFFER_SIZE = 2048;

	public byte[] encrypt(byte[] iv, byte[] b) {
		return encrypt(iv, 0, b, 0, b.length);
	}

	public byte[] encrypt(byte[] iv, int ivOffset, byte[] b, int off, int len) {
		setBuffer(len);
		byte[] result = new byte[encrypt(iv, ivOffset, b, off, len, buffer, 0)];
		System.arraycopy(buffer, 0, result, 0, result.length);
		return result;
	}

	public int encrypt(byte[] iv, int ivOffset, byte[] input, int inputOffset, int inputLen,
			byte[] output, int outputOffset) {
		init(iv, ivOffset);
		int outputLen = update(input, inputOffset, inputLen, output, outputOffset);
		return outputLen + doFinal(output, outputOffset + outputLen);
	}

	public OutputStream encrypt(OutputStream out, byte[] iv) {
		return encrypt(out, iv, 0);
	}

	public OutputStream encrypt(final OutputStream out, byte[] iv, int ivOffset) {
		init(iv, ivOffset);
		return new OutputStream() {
			@Override
			public void write(int b) throws IOException {
				write(new byte[] {(byte) b});
			}

			@Override
			public void write(byte[] b, int off, int len) throws IOException {
				setBuffer(len);
				out.write(buffer, 0, update(b, off, len, buffer, 0));
			}

			@Override
			public void flush() throws IOException {
				out.flush();
			}

			@Override
			public void close() throws IOException {
				setBuffer(blockSize);
				out.write(buffer, 0, doFinal(buffer, 0));
				out.close();
			}
		};
	}

	protected boolean setBuffer(int len) {
		int bufferSize = (len + blockSize * 2 + CIPHER_BUFFER_SIZE) / CIPHER_BUFFER_SIZE * CIPHER_BUFFER_SIZE;
		if (buffer == null || buffer.length < bufferSize) {
			buffer = new byte[bufferSize];
			return true;
		} else {
			return false;
		}
	}
*/
}